package logo;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Polygon;

public class Turtle {

	static private Turtle _t = null;
	
	private double _x;
	private double _y;
	private int _angle;
	private boolean _up = false;
	private final int triangleX[] = { 5,  0, -5,  5};
	private final int triangleY[] = {-5,  8, -5, -5};
	private Graphics _graphics;

	public static Turtle getTurtle() {
		if (_t != null)
			return _t;
		_t = new Turtle();
		_t.init();
		return _t;
	}
	
	public Turtle()
	{
		_graphics = null;
	}
	
	public void setGraphics(Graphics in)
	{
		_graphics = in;
	}

	private void init() {
		_x = 400;
		_y = 300;
		setAngle(180);
		_up = false;
	}
	
	private int getAngle() {
		return _angle;
	}

	private void setAngle(int angle) {
		_angle = angle % 360;
	}

	private int[] getBaseTriangleX()
	{
		int result[] = triangleX.clone();
		for (int i = 0; i < result.length; ++i)
			result[i] += _x;
		return result;
	}

	private int[] getBaseTriangleY()
	{
		int result[] = triangleY.clone();
		for (int i = 0; i < result.length; ++i)
			result[i] += _y;
		return result;
	}

	private double getAngleInRadians()
	{
		return ((double)_angle * Math.PI) / 180;
	}
	
	private int[] getXPolygon()
	{
		int x[] = getBaseTriangleX();
		int y[] = getBaseTriangleY();
		int result[] = x;
		int u = (x[0] + x[1] + x[2]) / 3;
		int v = (y[0] + y[1] + y[2]) / 3;
		
		result[0] = (int)(u + (x[0]-u) * Math.cos(getAngleInRadians()) + (y[0]-v) * Math.sin(getAngleInRadians()));
		result[1] = (int)(u + (x[1]-u) * Math.cos(getAngleInRadians()) + (y[1]-v) * Math.sin(getAngleInRadians()));
		result[2] = (int)(u + (x[2]-u) * Math.cos(getAngleInRadians()) + (y[2]-v) * Math.sin(getAngleInRadians()));
		result[3] = result[0];
		return result;
	}
	
	private int[] getYPolygon()
	{
		int x[] = getBaseTriangleX();
		int y[] = getBaseTriangleY();
		int result[] = y;
		int u = (x[0] + x[1] + x[2]) / 3;
		int v = (y[0] + y[1] + y[2]) / 3;

		result[0] = (int) (v + (y[0] - v) * Math.cos(getAngleInRadians()) - (x[0] - u) * Math.sin(getAngleInRadians()));
		result[1] = (int) (v + (y[1] - v) * Math.cos(getAngleInRadians()) - (x[1] - u) * Math.sin(getAngleInRadians()));
		result[2] = (int) (v + (y[2] - v) * Math.cos(getAngleInRadians()) - (x[2] - u) * Math.sin(getAngleInRadians()));
		result[3] = result[0];
		return result;
	}
	
	private Polygon getTurtlePolygon()
	{
		Polygon result = new Polygon(getXPolygon(),getYPolygon(),4);
		return result;
	}
	
	public void paintTurtle() {
		if (_up)
			_graphics.setColor(Color.gray);
		else
			_graphics.setColor(Color.white);
		
		_graphics.drawPolygon(getTurtlePolygon());
	}
	
	public void forward(double length)
	{
		double[] origin = {_x, _y};
		double[] result = origin.clone();
		
		result[0] = origin[0] + length * Math.sin(getAngleInRadians());
		result[1] = origin[1] + length * Math.cos(getAngleInRadians());

		_x = result[0];
		_y = result[1];
		
		if (_up == false)
		{
			_graphics.setColor(Color.red);
			_graphics.drawLine((int)Math.round(origin[0]), (int)Math.round(origin[1]), (int)Math.round(result[0]), (int)Math.round(result[1]));
		}
	}

	public void up()
	{
		_up = true;
	}

	public void down()
	{
		_up = false;
	}
	
	public void left(int degrees)
	{
		setAngle(getAngle() + degrees);
	}
	
	public void right(int degrees)
	{
		setAngle(getAngle() - degrees);
	}
	
	public void reset()
	{
		init();
	}
}
